package com.a01_2021.thousandstimes.saas.service.impl;

import com.a01_2021.thousandstimes.exception.CustomException;
import com.a01_2021.thousandstimes.exception.CustomExceptionType;
import com.a01_2021.thousandstimes.saas.entity.SysInstance;
import com.a01_2021.thousandstimes.saas.mapper.SysInstanceMapper;
import com.a01_2021.thousandstimes.saas.service.SysInstanceService;
import com.a01_2021.thousandstimes.utils.SqlUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author FRQ
 * @since 2021-02-22
 */
@Service
public class SysInstanceServiceImpl extends ServiceImpl<SysInstanceMapper, SysInstance> implements SysInstanceService {

    @Resource
    private SysInstanceMapper sysInstanceMapper;

    @Resource
    private SqlUtils sqlUtils;//特殊SQL执行工具

    /**
     * 建立新实例
     *
     * @param instanceName 新的实例名
     * @return 返还新实例的Admin随机密码
     */
    public Map<String, String> addInstance(String instanceName, long userId) throws SQLException, ClassNotFoundException {
        //新建数据库
        sqlUtils.addDatabase(instanceName);
        //实例表中插入新数据库
        SysInstance sysInstance = new SysInstance();
        sysInstance.setInitDate(LocalDateTime.now());
        sysInstance.setName(instanceName);
        sysInstance.setUserId(userId);
        sysInstance.setExpireDate(LocalDateTime.now().plusDays(7));
        sysInstanceMapper.insert(sysInstance);
        //向动态数据库中添加新实例数据库
        sqlUtils.addDataSource(sysInstance.getId(), instanceName);
        //初始化表结构
        sqlUtils.initInstance(instanceName);
        //初始化数据库数据
        String tempPassword = String.valueOf(System.currentTimeMillis());//新实例临时管理员密码
        sqlUtils.initDatabase(String.valueOf(sysInstance.getId()), tempPassword);
        //返还临时用户数据
        Map<String, String> returnData = new HashMap<>();
        returnData.put("username", "admin");
        returnData.put("tempPassword", tempPassword);
        returnData.put("instanceId", String.valueOf(sysInstance.getId()));
        returnData.put("expireDate", String.valueOf(sysInstance.getExpireDate()));
        return returnData;
    }

    /**
     * 是否为现存实例
     *
     * @param instanceName 实例名
     * @return 若实例存在返还True, 不存在返还False
     */
    public boolean isInstance(String instanceName) {
        if (StringUtils.isEmpty(instanceName))
            return false;
        QueryWrapper<SysInstance> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", instanceName);
        SysInstance sysInstance = sysInstanceMapper.selectOne(queryWrapper);
        return sysInstance != null;
    }

    /**
     * 通过实例id查询是否为现存实例
     *
     * @param instanceId 实例id
     * @return 若实例存在返还True, 不存在返还False
     */
    public boolean isInstance(long instanceId) {
        QueryWrapper<SysInstance> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", instanceId);
        Integer count = sysInstanceMapper.selectCount(queryWrapper);
        return count > 0;
    }

    /**
     * 用于给实例延长租期
     *
     * @param instanceId 实例id
     * @param renewalDay 延长天数
     * @return 返还实例信息
     */
    public SysInstance renewalInstance(String instanceId, int renewalDay) throws CustomException {
        QueryWrapper<SysInstance> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", instanceId);
        SysInstance sysInstance = sysInstanceMapper.selectOne(queryWrapper);
        if(sysInstance==null)
            throw new CustomException(CustomExceptionType.INSTANCE_NOT_FOUND_ERROR, "不存在当前对应实例");
        if (sysInstance.getExpireDate().isBefore(LocalDateTime.now())) {
            //若实例已过期
            sysInstance.setExpireDate(LocalDateTime.now().plusDays(renewalDay));
        } else {
            //若实例未过期
            sysInstance.setExpireDate(sysInstance.getExpireDate().plusDays(renewalDay));
        }
        sysInstanceMapper.updateById(sysInstance);
        return sysInstance;
    }

    /**
     * 通过实例id获取实例信息
     *
     * @param instanceId 实例id
     * @return SysInstance查询实例对象
     * @throws CustomException 当实例不存在时抛出该异常
     */
    @Override
    public SysInstance getInstanceInfo(long instanceId) throws CustomException {
        if (!this.isInstance(instanceId)) {
            //非实例id
            throw new CustomException(CustomExceptionType.INSTANCE_NOT_FOUND_ERROR, "非存在实例");
        }
        return sysInstanceMapper.selectById(instanceId);
    }

    /**
     * 通过用户id查询对应实例id
     *
     * @param userId 用户id
     * @return 返还实例id
     * @throws CustomException 当实例不存在时抛出该异常
     */
    @Override
    public long getInstanceIdFromUserId(Long userId) throws CustomException {
        QueryWrapper<SysInstance> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        SysInstance sysInstance = sysInstanceMapper.selectOne(queryWrapper);
        if (sysInstance == null)
            throw new CustomException(CustomExceptionType.INSTANCE_NOT_FOUND_ERROR);
        return sysInstance.getId();
    }
}
